﻿using EasyLoger.Configuration;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Reflection;
using System.Threading;

namespace EasyLoger
{
    public class Loger : IDisposable
    {
        private static Loger _instance;
        private LogConfig config;
        private ILoger loger;
        private Queue<LogMessage> msgs;
        private bool state = false;
        public void Dispose()
        {
            this.state = false;
        }
        public static Loger GetInstance()
        {
            if (Loger._instance == null)
            {
                Loger._instance = new Loger();
            }
            return Loger._instance;
        }
        private Loger()
        {
            this.config = (LogConfig)ConfigurationManager.GetSection("easylog");
            this.loger = this.getLoger();
            this.msgs = new Queue<LogMessage>();
            ThreadStart start = new ThreadStart(this.Work);
            Thread thread = new Thread(start);
            this.state = true;
            thread.Start();
        }
        private ILoger getLoger()
        {
            string defaultlogType = this.config.DefaultlogType;
            string assemblyString = defaultlogType.Split(new char[]
			{
				','
			})[1];
            string typeName = defaultlogType.Split(new char[]
			{
				','
			})[0];
            object[] args = new object[]
			{
				this.config.CfgNode
			};
            object obj = Assembly.Load(assemblyString).CreateInstance(typeName, false, BindingFlags.Default, null, args, null, null);
            return (ILoger)obj;
        }
        private void InternalWrit(LogMessage msg)
        {
            this.loger.Write(msg);
        }
        private void Work()
        {
            while (true)
            {
                if (this.msgs.Count > 0)
                {
                    LogMessage logMessage = null;
                    lock (this.msgs)
                    {
                        logMessage = this.msgs.Dequeue();
                    }
                    if (logMessage != null)
                    {
                        this.InternalWrit(logMessage);
                    }
                }
                else
                {
                    if (!this.state)
                    {
                        break;
                    }
                    Thread.Sleep(10);
                }
            }
            this.loger.Stop();
        }
        public void Write(LogMessage msg)
        {
            if (msg != null)
            {
                lock (this.msgs)
                {
                    this.msgs.Enqueue(msg);
                }
            }
        }
    }
}

